const path = require('path')
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const glob = require('glob');
const PurgecssPlugin = require("purgecss-webpack-plugin"); // 可以出去未使用的css
const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin');
// const PreloadWebpackPlugin = require('preload-webpack-plugin');
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');
const smw = new SpeedMeasureWebpackPlugin(); // bug: 跟mini-css-extract-plugin一起使用报错
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');// 分析打包图
const PATHS = {
  src: path.join(__dirname, 'src')
}
module.exports = {
  mode: 'production',
  devtool: false,
  entry: {
    // main: './src/main.js',
    // index: './src/index.js'
    page1: './src/page1.js',
    page2: './src/page2.js',
    page3: './src/page3.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  resolve: {
    extensions: ['.js', '.css', '.scss', '.vue'],//1.尝试按顺序解析后缀名，默认['.js', '.json', '.wasm']
    alias: {// 2.配置别名：1.方便引入，2.bootstrap不需要按模块查找规则，加快查找速度
      '@': path.resolve(__dirname, 'src'),
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      bootstrap: path.resolve(__dirname, 'node_modules/bootstrap/dist/css/bootstrap.css')
    },
    //如果你想要添加一个目录到模块搜索目录，此目录优先于 node_modules/ 搜索
    modules: ['node_modules'], // 3.告诉webpack解析模块时应该搜索的目录
    // mainFields: ['browser', 'module', 'main'],// 4.从npm 包中导入模块时，此选项将决定在package.json中使用那个字段导入模块
    mainFiles: ['index'],//5. 解析目录时要使用目录中的文件名
  },
  resolveLoader: {// 6.这组选项与上面的relove对象属性集合相同，但仅用于解析webpack的loader包
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    extensions: ['js', 'jsx'],
    mainFields: ['module', 'main']
  },
  module: {
    // noParse: /jquery|lodash/, // 7.不需要解析依赖（即无依赖） 的第三方大型类库等，可以通过这个字段来配置，以提高整体的构建速度
    // noParse: (content) => /jquery|lodash/.test(content)

    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.js$/,
        use: [
          {
            loader: 'thread-loader',// 10.把这个loader放在其他loader之前，这个loader之后的loader就会在一个单独的worker池中运行
            options: {
              worker: 3 // 配置线程池个数，打开几个worker池，一般打开cpu核数-1
            }
          },
          {
            loader: 'babel-loader',
            options: {
              presets: [['@babel/preset-env']] // 添加预设
            }
          }
        ]
      }
    ]
  },
  optimization: {
    // splitChunks: {
    //   chunks: 'all',
    //   minSize: 0,
    //   minRemainingSize: 0,
    //   minChunks: 1,
    //   maxAsyncRequests: 30,
    //   maxInitialRequests: 30,
    //   enforceSizeThreshold: 50000,
    //   cacheGroups: {
    //     defaultVendors: {
    //       test: /[\\/]node_modules[\\/]/,
    //       priority: -10,
    //       reuseExistingChunk: true,
    //     },
    //     default: {
    //       minChunks: 2,
    //       priority: -20,
    //       reuseExistingChunk: true,
    //     },
    //   },
    // },
    splitChunks: {
      chunks: 'all',//代码分割应用于哪些情况 initial/async/all=async+initial
      minSize: 0,//分割出去的代码块最小的尺寸多大,默认是30K 0就是不限制 ,只要符合分割的要求就会分割
      minChunks: 2,//如果一个模块被多少个入口引入了才会分割.
      maxAsyncRequests: 3,//限制异步模块内部并行加载的请最大请求数,说白了就是每个import()里面最大的请求数
      maxInitialRequests: 5,//限制同步模块内部并行加载的请最大请求数,
      name: false,//打包后的名称,默认规则是 分割名称~
      automaticNameDelimiter: '~', //分割符
      cacheGroups: {
        //设置缓存组用来抽取满足不同规则 的chunk
        vendors: {//lodash既然在node_modules里,肯定是属于vendor缓存组
          chunks: 'all',
          test: /node_modules/,//如果这个模块request路径里面包含node_modules
          priority: -10
        },
        default: {
          chunks: 'all',
          minSize: 0,
          minChunks: 2, //如果一个模块被至少2个入口引用了,那么就属于这个组
          priority: -20
        }
        //有些模块,比如说jquery按上面的配置,它会同时属于vendors和default两个缓存组
      }

    }

  },
  plugins: [
    // new BundleAnalyzerPlugin({
    //   analyzerPort: 8889,
    // }),
    // 多页面chunk插入，设置页面不同title，可配置title参数，具体可网上查
    new HtmlWebpackPlugin({ template: './src/index.html', filename: 'page1.html', chunks: ['page1'] }),
    new HtmlWebpackPlugin({ template: './src/index.html', filename: 'page2.html', chunks: ['page2'] }),
    new HtmlWebpackPlugin({ template: './src/index.html', filename: 'page3.html', chunks: ['page3'] }),
    // new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['index'] }),
    // new HtmlWebpackPlugin({ template: './src/main.html', filename: 'main.html', chunks: ['main', 'index'] }),
    // new PreloadWebpackPlugin(),
    new webpack.IgnorePlugin({// 8.IgnorePlugin用于忽略某些特定的模块，让 webpack 不把这些指定的模块打包进去
      contextRegExp: /moment$/,// Supported in webpack 4 and earlier, unsupported in webpack 5:
      resourceRegExp: /^\.\/locale/
    }),
    new MiniCssExtractPlugin({
      filename: '[name].css'
    }),
    new PurgecssPlugin({ // 9.除去未使用的css，一般与glob，glob-all配合使用，必须与mini-css-extract-plugin配合使用
      paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true })// glob获取符合指定条件下的所有文件
    })
  ]
}